﻿using System;
using System.Collections.Generic;
using System.Linq;
using DCS.Business.Model;
using DCS.DataProvider;

namespace DCS.Business.Manager
{
    public class DCSFileManager
    {
        private IDataProvider provider;
        static log4net.ILog Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        static object locker = new object();

        public DCSFileManager(IDataProvider p)
        {
            this.provider = p;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="files"></param>
        /// <returns></returns>
        public int DetectNewDCSFiles(List<DCSFile> files)
        {
            int count = 0;
            foreach (var item in files)
            {
                try
                {
                    provider.CreateDCSFile(item);
                    count++;
                }
                catch (Exception e)
                {
                    Logger.Error("Error During CreateDCSFile", e);
                    continue;
                }
            }

            return count;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        public int DetectNewDCSFile(DCSFile file)
        {
            try
            {
                provider.CreateDCSFile(file);
                return 1;
            }
            catch (Exception e)
            {
                Logger.Error("Error During CreateDCSFile", e);
                return 0;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="files"></param>
        /// <returns></returns>
        public int UpdateDCSFilesStatus(List<DCSFile> files)
        {
            var group = files.GroupBy(f => f.Status);

            try
            {

                foreach (var items in group)
                {
                    var status = items.Key;
                    int[] ids = items.ToDictionary(f => f.FileId).Keys.ToArray();
                    provider.BatchUpdateDCSFilesStatus(ids, status);
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Error during UpdateDCSFilesStatus", ex);
                return 0;
            }

            return files.Count;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        //public List<string> GetRecentFileNames(int recentDays)
        //{
        //    return provider.GetRecentFileNames(recentDays);
        //}

        public Dictionary<string,DateTime> GetRecentFileNames(int recentDays)
        {
            Dictionary<string, DateTime> result = null;

            try
            {
                lock (locker)
                {
                    result = provider.GetRecentFileNames(recentDays);
                }
            }
            catch(Exception e)
            {
                Logger.Error("Error in GetRecentFileNames", e);
            }

            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dCSFile"></param>
        public DCSFile CreateDCSFile(DCSFile dCSFile)
        {
            return provider.CreateDCSFile(dCSFile);
        }

        /// <summary>
        /// 
        /// </summary>
        public void DeleteDcsFile(List<string> fileList,string messageType)
        {
             provider.DeleteExitFileList(fileList,messageType);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dCSFile"></param>
        public void UpdateDCSFile(DCSFile dCSFile)
        {
            provider.UpdateDCSFile(dCSFile);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileIds"></param>
        /// <param name="dCSFiles"></param>
        public List<DCSFile> GetDCSFilesByMessageType(string messageType, FileStatus status, int rowCount, FileStatus lockStatus = 0, bool fullMatch = true)
        {
            return provider.GetDCSFilesByMessageType(messageType, status, rowCount, lockStatus, fullMatch);
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileIds"></param>
        /// <param name="dCSFiles"></param>
        public List<DCSFile> GetDCSFilesGroupByMessageType(string messageType, FileStatus status, int groupCount)
        {
            return provider.GetDCSFilesGroupByMessageType(messageType, status, groupCount);
        }

        /// <summary>
        /// 获取文件来进行解析
        /// </summary>
        /// <param name="batchSize">批大小</param>
        /// <param name="MessageType">报文类型</param>
        /// <returns></returns>
        public List<DCSFile> GetFilesToParse(int batchSize, string MessageType)
        {
            List<DCSFile> list = null;

            list = provider.GetDCSFilesByMessageType(MessageType, FileStatus.FinishDownload, batchSize, FileStatus.StartParse);
            list.ForEach(d => d.Status = FileStatus.StartParse);

            return list;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="batchSize"></param>
        /// <param name="MessageType"></param>
        /// <returns></returns>
        public List<DCSFileGroup> GetFilesGroupToParse(int batchSize, string MessageType)
        {
            List<DCSFile> list = null;
            List<DCSFileGroup> result = new List<DCSFileGroup>();

            list = provider.GetDCSFilesGroupByMessageType(MessageType, FileStatus.FinishDownload, batchSize, FileStatus.StartParse);
            list.ForEach(d => d.Status = FileStatus.StartParse);

            var groups = list.GroupBy(d => d.RemoteFileName.Substring(0, d.RemoteFileName.IndexOf("_PART")));
            var cannot = new List<DCSFile>();

            foreach (var item in groups)
            {
                var g = new DCSFileGroup();
                g.AddRange(item.ToList());

                if (g.Validate)
                {
                    result.Add(g);
                }
                else
                {
                    cannot.AddRange(item.ToList());
                }
            }

            //cannot.ForEach(d => d.Status = FileStatus.FinishDownload);
            UpdateDCSFilesStatus(cannot);

            return result;
        }


    }
}
